#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "mylog.hpp"
#include "PthreadPool.hpp"
#include "task.hpp"
#include "daemon.hpp"
#include "ditcinit.hpp"
Log lg;
static const char* defaultip = "0.0.0.0";
static const int backlog = 10;

enum{
    SOCKETERR = 1,
    BINDERR,
    LISTENERR,

};

class TcpServer
{
public:
    TcpServer(const uint16_t & port,const std::string &ip = defaultip)
        :_listensockfd(-1)
        ,_port(port)
        ,_ip(ip)
    {}
    ~TcpServer()
    {}
    void initserver()
    {
        
        _listensockfd = socket(AF_INET,SOCK_STREAM,0);
        if(_listensockfd < 0)
        {
            lg(FATAL,"socket errno:%d,strerror:%s",errno,strerror(errno));
            exit(SOCKETERR);
        }
        
        lg(INFO,"socket success,initsockfd:%d ",_listensockfd);

        struct sockaddr_in local;
        bzero(&local,sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = inet_addr(_ip.c_str());

        socklen_t len = sizeof(local);
        if(bind(_listensockfd,(const sockaddr *)(&local),len) < 0)
        {
            lg(FATAL,"bind errno:%d,strerror:%s",errno,strerror(errno));
            exit(BINDERR);
        }
        lg(INFO,"bind success");

        //设置监听状态
        if(listen(_listensockfd,backlog) < 0)
        {
            lg(FATAL,"listen errno:%d,strerror:%s",errno,strerror(errno));
            exit(LISTENERR);
        }
        lg(INFO,"listen success");
    }

    void run()
    {
        MyDitc::Ditc *dc  = new MyDitc::Ditc();
        MyDaemon::Daemon();
        
        mythpool::ThPool<mytask::Task>::GetOnceCase()->inittp();
        //tp->inittp();
        while(true)
        {
            struct sockaddr_in client;
            bzero(&client,sizeof(client));
            socklen_t  len = sizeof(client);

            //与客户端建立连接
            int sockfd = accept(_listensockfd,(sockaddr *)(&client),&len);
            if(sockfd < 0)
            {
                lg(WARNING,"accept errno:%d,strerror:%s",errno,strerror(errno));
                continue;
            }   
            
            //获取客户端端口和ip
            uint16_t clientport = ntohs(client.sin_port);
            char clientip[16];
            if(inet_ntop(client.sin_family,&(client.sin_addr),clientip,sizeof(clientip)) == nullptr)
            {
                lg(WARNING,"inet_ntop errno:%d,strerror:%s",errno,strerror(errno));
                continue;
            }

            lg(INFO,"accept success");

            //处理用户数据
            //单进程版
            // sercontent(sockfd,clientport,clientip);
            // close(sockfd);

            //线程池
            mytask::Task t(sockfd,clientport,clientip,dc);
            mythpool::ThPool<mytask::Task>::GetOnceCase()->push(t);
            //tp->push(t);
        }        
    }


    // void sercontent(const int& sockfd,const uint16_t& clientport,const std::string& clientip)
    //     {
    //         char buf[SIZE];
    //         int n = read(sockfd,buf,sizeof(buf));
    //         if(n > 0)
    //         {
    //             buf[n] = 0;
    //             std::cout << buf << std::endl;

    //             std::string str = buf;
    //             str += "已处理";

    //             write(sockfd,str.c_str(),str.size());
    //         }
    //         else if(n == 0)
    //         {
    //             lg(WARNING,"client quit");
    //         }
    //         else
    //         {
    //             lg(WARNING,"read errno:%d,strerror:%s",errno,strerror(errno));
    //         }

    //     }
private:
    int _listensockfd;
    uint16_t _port;
    std::string _ip;
};